// 自定义遍历器  这种自定义的,感觉像是一个闭包,只不过调用方式是通过next调用内部函数
{
  function makeIte (arr) {
    let index = 0
    return {
      next: function () {
        return {
          value: index < arr.length ? arr[index++] : undefined,
          done: index < arr.length ? false : true}
      }
    }
  }
  let arr = [1, 2, 3, 4]
  let iterator = makeIte(arr)
  console.log(iterator.next())
  console.log(iterator.next())
  console.log(iterator.next())
  console.log(iterator.next())
  console.log(iterator.next())
}

// 对象上部署Iterator
{
  let obj = {
    data: ['hello', 'world'],
    [Symbol.iterator] () {
      let index = 0
      return {
        next: () => {
          if (index < this.data.length) {
            return {
              value: this.data[index++],
              done: false
            }
          } else {
            return {
              value: undefined,
              done: true
            }
          }
        }
      }
    }
  }
  let ite = obj[Symbol.iterator]()
  console.log(ite.next()) // { value: 'hello', done: false }
  console.log(ite.next()) // { value: 'world', done: false }
  console.log(ite.next()) // { value: undefined, done: true }
}


// map
{
  let map = new Map()
  map.set('a', 1)
  map.set('b', 2)
  map.set('c', 3)
  let ite = map[Symbol.iterator]()
  console.log(ite.next())
  console.log(ite.next())
  console.log(ite.next())
  console.log(ite.next())
  // { value: [ 'a', 1 ], done: false }
  // { value: [ 'b', 2 ], done: false }
  // { value: [ 'c', 3 ], done: false }
  // { value: undefined, done: true }
}


// 类似数组对象
{
  let iterable = {
    0: 'a',
    1: 'b',
    2: 'c',
    length: 3
  }
  // console.log(...iterable) // 报错,因为没部署Symbol.iterator接口
  console.log(Array.from(iterable)) // [ 'a', 'b', 'c' ]

  let iterable2 = {
    0: 'a',
    1: 'b',
    2: 'c',
    length: 3,
    [Symbol.iterator]: Array.prototype[Symbol.iterator]
  }
  // let ite = iterable[Symbol.iterator]
  console.log([...iterable2]) // [ 'a', 'b', 'c' ]
  let ite = iterable2[Symbol.iterator]()
  console.log(ite.next()) // { value: 'a', done: false }
  console.log(ite.next()) // { value: 'b', done: false }
  console.log(ite.next()) // { value: 'c', done: false }
  console.log(ite.next()) // { value: undefined, done: true }
}
// 类数组对象
{
  let iterable2 = {
    0: 'a',
    1: 'b',
    5: 'c',
    length: 3,
    [Symbol.iterator]: Array.prototype[Symbol.iterator]
  }
  for (let v of iterable2) {
    console.log(v) // a b undefined
  }
  console.log(Array.from(iterable2)) // [a, b, undefined]
}
